/**
 * 
 */
package qy.jalgotrade.stratanalyzer.returns;

import java.util.HashMap;
import java.util.Map;

import qy.jalgotrade.bar.Bars;
import qy.jalgotrade.event.Event;
import qy.jalgotrade.stratanalyzer.StrategyAnalyzer;
import qy.jalgotrade.strategy.BaseStrategy;

/**
 * @author c-geo
 *
 */
public class ReturnsAnalyzerBase extends StrategyAnalyzer {

	private Event __event;

	private TimeWeightedReturns __portfolioReturns;

	public static StrategyAnalyzer getOrCreateShared(BaseStrategy strat) throws Exception {

		String name = ReturnsAnalyzerBase.class.getSimpleName();
		// Get or create the shared ReturnsAnalyzerBase.
		StrategyAnalyzer ret = strat.getNamedAnalyzer(name);
		if (ret == null) {
			ret = new ReturnsAnalyzerBase();
			strat.attachAnalyzerEx(ret, name);
		}
		return ret;
	}

	/**
	 * 
	 */
	public ReturnsAnalyzerBase() {

		super();
		__event = new Event("rtnstratana-new-return-event");
		__portfolioReturns = null;
	}

	/**
	 * <pre>
	 * An event will be notified when return are calculated at each bar. The hander should receive 1 parameter:
	 * 1: The current datetime.
	 * 2: This analyzer's instance
	 * </pre>
	 * 
	 * @return
	 */
	public Event getEvent() {

		return __event;
	}

	public double getNetReturn() {

		return __portfolioReturns.getLastPeriodReturns();
	}

	public double getCumulativeReturn() {

		return __portfolioReturns.getCumulativeReturns();
	}

	/* (non-Javadoc)
	 * @see qy.jalgotrade.stratanalyzer.StrategyAnalyzer#attached(qy.jalgotrade.strategy.BaseStrategy)
	 */
	@Override
	public void attached(BaseStrategy strat) {

		__portfolioReturns = new TimeWeightedReturns(strat.getBroker().getEquity());
	}

	/* (non-Javadoc)
	 * @see qy.jalgotrade.stratanalyzer.StrategyAnalyzer#beforeOnBars(qy.jalgotrade.strategy.BaseStrategy, qy.jalgotrade.bar.Bars)
	 */
	@Override
	public void beforeOnBars(BaseStrategy strat, Bars bars) {

		__portfolioReturns.update(strat.getBroker().getEquity());

		// Notify that new returns are available.
		Map<String, Object> params = new HashMap<>();
		params.put("dateTime", bars.getDateTime());
		params.put("returnsAnalyzerBase", this);

		__event.emit(__event.getName(), params);
	}
}
